﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using Beeldbankmvc.ViewModels;

namespace Beeldbankmvc.Models
{
    public class ReactionRepository
    {
        BeeldbankLinqDataContext db = new BeeldbankLinqDataContext();

        public IQueryable<BEELDBANK_REACTIE> FindAllSorted(int pageSize, int pageIndex, string identityName, int? orderBy, bool? includeClosed)
        {
            //
            // Skipping Subject type 6, since these are not for the Reactions module, but for the Unknown Images section
            //
            MembershipUser currentUser = Membership.GetUser(identityName);

            bool includeClosedItems = false;
            if (includeClosed.HasValue)
                includeClosedItems = includeClosed.Value;

            switch (orderBy.Value)
            {
                // order by status
                case 1:
                    var reactionsByStatus = from r in FindAllPendingReactions(includeClosedItems)
                                            where r.Subject != "6"
                                            orderby r.Status ascending, r.Datum descending
                                            select r;
                    return reactionsByStatus.Skip(pageIndex * pageSize).Take(pageSize);
                // order by subject
                case 2:
                    var reactionsBySubject = from r in FindAllPendingReactions(includeClosedItems)
                                             where r.Subject != "6"
                                             orderby r.Subject ascending, r.Datum descending
                                             select r;

                    return reactionsBySubject.Skip(pageIndex * pageSize).Take(pageSize);
                // order by category
                case 3:
                    var reactionsByCategory = from r in FindAllPendingReactions(includeClosedItems)
                                              where r.Subject != "6"
                                              orderby r.Category ascending, r.Datum descending
                                              select r;
                    return reactionsByCategory.Skip(pageIndex * pageSize).Take(pageSize);
                // only mediaObjectReactions by date
                case 4:
                    var mediaObjectReactionsByDate = from r in FindAllOnlyMediaObect(identityName, includeClosedItems)
                                                     where r.Subject != "6"
                                                     orderby r.Datum descending
                                                     select r;
                    return mediaObjectReactionsByDate.Skip(pageIndex * pageSize).Take(pageSize);
                // order by date
                default:
                    if (Roles.IsUserInRole("Administrator"))
                    {
                        var reactionsByDate = from r in FindAllPendingReactions(includeClosedItems)
                                              where r.Subject != "6"
                                              orderby r.Datum descending
                                              select r;
                        return reactionsByDate.Skip(pageIndex * pageSize).Take(pageSize);
                    }
                    else
                    {
                        var reactionsByDate = from r in FindAllNoMediaObect()
                                              where r.Subject != "6"
                                              orderby r.Datum descending
                                              select r;
                        return reactionsByDate.Skip(pageIndex * pageSize).Take(pageSize);
                    }
            }
        }

        public void updateMediaObjectReactionStatus(int Id, int reactionStatus)
        {
            BEELDBANK_REACTIE Reaction = FindOne(Id);

            Reaction.MediaObjectVerwerkingsStatus = reactionStatus;

            // Set Status to Gesloten as well
            Reaction.Status = 4;

            Update(Reaction);
        }

        public IEnumerable<mailInformation> getmailInformation(int Id)
        {
            var mail = from o in db.BEELDBANK_REACTIEs
                       where o.Id == Id
                       select new mailInformation
                        {
                            fromEmail = o.MediaObjectEigenaarEmail,
                            fromName = o.MediaObjectEigenaarNaam,
                            toEmail = o.EmailAdres,
                            toName = o.Naam
                        };
            return mail;
        }

        public int getNumberOfReactionRows(string identityName, bool? includeClosed)
        {
            MembershipUser currentUser = Membership.GetUser(identityName);

            bool includeClosedItems = false;
            if (includeClosed.HasValue)
                includeClosedItems = includeClosed.Value;

            if (Roles.IsUserInRole("Administrator"))
                return FindAllPendingReactions(includeClosedItems).Count();
            else
                return FindAllNoMediaObect().Count();
        }

        public int getNumberOfReactionRowsOnlyMediaObject(string identityName, bool includeClosed)
        {
            return FindAllOnlyMediaObect(identityName, includeClosed).Count();
        }

        public int getNumberOfReactionRows(DateTime fromDate, DateTime toDate)
        {
            var allResultsInTimeFrame = from o in FindAllNoMediaObect()
                                        where o.Datum > fromDate && o.Datum < toDate
                                        select o;

            return allResultsInTimeFrame.Count();
        }

        public int getNumberOfMediaReactionRows(DateTime fromDate, DateTime toDate)
        {
            var allResultsInTimeFrame = from o in FindAllOnlyMediaObect("", true)
                                        where o.Datum > fromDate && o.Datum < toDate
                                        select o;

            return allResultsInTimeFrame.Count();
        }

        public IEnumerable<ReactionModel> getSortedReactionsByTimeFrame(DateTime fromDate, DateTime toDate, int pageSize, int pageIndex, bool? orderByStatus)
        {
            if (orderByStatus.Value == true)
            {
                var allResultsInTimeFrame = from o in FindAllNoMediaObect()
                                            where o.Datum > fromDate && o.Datum < toDate
                                            orderby o.Status ascending, o.Datum descending
                                            select new ReactionModel
                                            {
                                                Id = o.Id,
                                                Datum = o.Datum,
                                                Category = o.Category,
                                                Subject = o.Subject,
                                                Email = o.EmailAdres,
                                                Name = o.Naam,
                                                Message = o.Boodschap,
                                                Status = o.BEELDBANK_REACTIESTATUS.Name
                                            };
                return allResultsInTimeFrame.Skip(pageIndex * pageSize).Take(pageSize);
            }
            else
            {
                var allResultsInTimeFrame = from o in FindAllNoMediaObect()
                                            where o.Datum > fromDate && o.Datum < toDate
                                            orderby o.Datum descending
                                            select new ReactionModel
                                            {
                                                Id = o.Id,
                                                Datum = o.Datum,
                                                Category = o.Category,
                                                Subject = o.Subject,
                                                Email = o.EmailAdres,
                                                Name = o.Naam,
                                                Message = o.Boodschap,
                                                Status = o.BEELDBANK_REACTIESTATUS.Name
                                            };
                return allResultsInTimeFrame.Skip(pageIndex * pageSize).Take(pageSize);
            }
        }

        public IEnumerable<ReactionModel> getSortedMediaReactionsByTimeFrame(DateTime fromDate, DateTime toDate, int pageSize, int pageIndex, bool? orderByStatus)
        {
            if (orderByStatus.Value == true)
            {
                var allResultsInTimeFrame = from o in FindAllOnlyMediaObect("", true)
                                            where o.Datum > fromDate && o.Datum < toDate
                                            orderby o.Status ascending, o.Datum descending
                                            select new ReactionModel
                                            {
                                                Id = o.Id,
                                                Datum = o.Datum,
                                                Category = o.Category,
                                                Subject = o.Subject,
                                                Email = o.EmailAdres,
                                                Name = o.Naam,
                                                Message = o.Boodschap,
                                                MediaObjectEigenaarNaam = o.MediaObjectEigenaarNaam,
                                                Status = o.BEELDBANK_REACTIESTATUS.Name
                                            };
                return allResultsInTimeFrame.Skip(pageIndex * pageSize).Take(pageSize);
            }
            else
            {
                var allResultsInTimeFrame = from o in FindAllOnlyMediaObect("", true)
                                            where o.Datum > fromDate && o.Datum < toDate
                                            orderby o.Datum descending
                                            select new ReactionModel
                                            {
                                                Id = o.Id,
                                                Datum = o.Datum,
                                                Category = o.Category,
                                                Subject = o.Subject,
                                                Email = o.EmailAdres,
                                                Name = o.Naam,
                                                Message = o.Boodschap,
                                                MediaObjectEigenaarNaam = o.MediaObjectEigenaarNaam,
                                                Status = o.BEELDBANK_REACTIESTATUS.Name
                                            };
                return allResultsInTimeFrame.Skip(pageIndex * pageSize).Take(pageSize);
            }
        }

        public IQueryable<BEELDBANK_REACTIE> FindAllOnlyMediaObect(string identityName, bool includeClosed)
        {
            MembershipUser currentUser = Membership.GetUser(identityName);
            if (Roles.IsUserInRole("Administrator"))
            {
                if (includeClosed)
                    return db.BEELDBANK_REACTIEs.Where(p => (p.MediaObjectId != null && p.MediaObjectId != 0));
                else
                    return db.BEELDBANK_REACTIEs.Where(p => (p.MediaObjectId != null && p.MediaObjectId != 0) && (p.MediaObjectVerwerkingsStatus == null || p.MediaObjectVerwerkingsStatus.Equals(1)));
            }
            else
            {
                if (identityName != "")
                    if (includeClosed)
                        return db.BEELDBANK_REACTIEs.Where(p => (p.MediaObjectId != null && p.MediaObjectId != 0) && p.MediaObjectEigenaarNaam == identityName);
                    else
                        return db.BEELDBANK_REACTIEs.Where(p => (p.MediaObjectId != null && p.MediaObjectId != 0) && p.MediaObjectEigenaarNaam == identityName && (p.MediaObjectVerwerkingsStatus == null || p.MediaObjectVerwerkingsStatus.Equals(1)));
                else
                    if (includeClosed)
                        return db.BEELDBANK_REACTIEs.Where(p => (p.MediaObjectId != null && p.MediaObjectId != 0));
                    else
                        return db.BEELDBANK_REACTIEs.Where(p => (p.MediaObjectId != null && p.MediaObjectId != 0) && (p.MediaObjectVerwerkingsStatus == null || p.MediaObjectVerwerkingsStatus.Equals(1)));
            }
        }

        public IQueryable<BEELDBANK_REACTIE> FindAllNoMediaObect()
        {
            return db.BEELDBANK_REACTIEs.Where(p => p.MediaObjectId == null || p.MediaObjectId == 0);
        }

        public IQueryable<BEELDBANK_REACTIE> FindAllPendingReactions(bool includeClosed)
        {
            if (includeClosed)
                return db.BEELDBANK_REACTIEs;
            else
                return db.BEELDBANK_REACTIEs.Where(p => !p.Status.Equals(4));
        }

        public IQueryable<BEELDBANK_REACTIE> FindNewReactionsForMediaObject(int MediaObjectId, string identityName)
        {
            MembershipUser currentUser = Membership.GetUser(identityName);
            if (Roles.IsUserInRole("Administrator"))
            {
                return db.BEELDBANK_REACTIEs.Where(p => p.MediaObjectId == MediaObjectId && (p.MediaObjectVerwerkingsStatus == null || p.MediaObjectVerwerkingsStatus.Equals(1)));
            }
            else
            {
                return db.BEELDBANK_REACTIEs.Where(p => p.MediaObjectId == MediaObjectId && p.MediaObjectEigenaarNaam == identityName && (p.MediaObjectVerwerkingsStatus == null || p.MediaObjectVerwerkingsStatus.Equals(1)));
            }
        }

        public IQueryable<BEELDBANK_REACTIE> FindReactionsForMediaObject(int MediaObjectId)
        {
            return db.BEELDBANK_REACTIEs.Where(p => p.MediaObjectId == MediaObjectId && (p.Subject.Equals(6)));
        }

        public void Update(BEELDBANK_REACTIE reaction)
        {
            BEELDBANK_REACTIE storedReaction = this.FindOne(reaction.Id);

            storedReaction.Boodschap = reaction.Boodschap;
            storedReaction.Category = reaction.Category;
            storedReaction.Subject = reaction.Subject;

            db.SubmitChanges();
        }

        public BEELDBANK_REACTIE FindOne(int id)
        {
            return db.BEELDBANK_REACTIEs.SingleOrDefault(m => m.Id == id);
        }

        public void AddFirst(ReactionModel model)
        {
            BEELDBANK_REACTIE reaction = new BEELDBANK_REACTIE();
            reaction.Datum = DateTime.Now;
            reaction.Status = 1;
            reaction.EmailAdres = model.Email;
            reaction.Naam = model.Name;
            reaction.Subject = model.Subject;
            reaction.Category = model.Category;
            reaction.Boodschap = model.Message;
            reaction.Telefoon = model.Telephone;
            reaction.MediaObjectId = model.MediaObjectId;
            reaction.MediaObjectEigenaarNaam = model.MediaObjectEigenaarNaam;
            reaction.MediaObjectEigenaarEmail = model.MediaObjectEigenaarEmail;
            reaction.MediaObjectTitel = model.MediaObjectTitel;
            reaction.MediaObjectOmschrijving = model.MediaObjectOmschrijving;
            reaction.MediaObjectLokatie = model.MediaObjectLocatie;

            db.BEELDBANK_REACTIEs.InsertOnSubmit(reaction);
            db.SubmitChanges();

            // Save a copy of the edited service call to the correspondence tabel
            BEELDBANK_REACTIE_CORRESPONDENTIE correspondence = new BEELDBANK_REACTIE_CORRESPONDENTIE();
            correspondence.Datum = DateTime.Now;
            correspondence.Status = 1;
            correspondence.Boodschap = model.Message;
            correspondence.Subject = model.Subject;
            correspondence.Category = model.Category;
            correspondence.IsVisitorResponse = true;
            correspondence.BEELDBANK_REACTIE = reaction;

            db.BEELDBANK_REACTIE_CORRESPONDENTIEs.InsertOnSubmit(correspondence);
            db.SubmitChanges();
        }

        public void Delete(BEELDBANK_REACTIE collection)
        {
            db.BEELDBANK_REACTIEs.DeleteOnSubmit(collection);
        }

        public void Save()
        {
            db.SubmitChanges();
        }
    }

    public class mailInformation
    {
        public string fromName { get; set; }
        public string fromEmail { get; set; }
        public string toName { get; set; }
        public string toEmail { get; set; }
    }
}